<?php
/**
 *    Copyright 2010 Show Framework(www.showframework.cn)
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 * 
 *        http://www.apache.org/licenses/LICENSE-2.0
 * 
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

/**
 * 系统默认路由器
 *
 * @package Show
 * @name Show_Router
 * @author show
 * @since v0.6
 */
class Show_Router implements Show_Router_Interface
{
    /**
     * 控制器名称
     *
     * @var string
     */
    private $controllerName;
    
    /**
     * Action名称
     *
     * @var string
     */
    private $actionName;
    
    /**
     * 控制器实例
     *
     * @var Show_Controller_Interface
     */
    private $controller;
    
    /**
     * 构造函数
     *
     * @return void
     */
    public function __construct()
    {
        $this->controllerName = '';
        $this->actionName = '';
        $this->controller = null;
    }
    
    /**
     * 路由
     *
     * @return void
     */
    public function dispatch()
    {
        $this->initControllerName();
        
        $this->initActionName();
        
        $this->instanceController();
        
        if ($this->controller instanceof Show_Controller_Interface) {
            $this->controller->init();
            if ($this->actionExist()) {
                $this->controller->{$this->actionName}();
            } else {
                $this->_404();
            }
        } else {
            $this->_404();
        }
    }
    
    /**
     * 解析命令之后发现无法找到对应的控制器或者Action的时候的该如何处理
     *
     * @return void
     */
    public function _404()
    {
        Show_Error::fatal('您所访问的页面不存在');
    }
    
    /**
     * 取得命令栈中对应位置
     *
     * @param int $position
     * @return string|null
     */
    protected function getParam($position)
    {
        return isset($GLOBALS['show']['command_stack'][$position]) ? $GLOBALS['show']['command_stack'][$position] : null;
    }
    
    /**
     * 初始化控制器名称
     *
     * @return void
     */
    protected function initControllerName()
    {
        if (empty($GLOBALS['show']['command_stack'][0])) {
            $controller = Show_App::config()->url->default->controller;
        } else {
            $controller = $GLOBALS['show']['command_stack'][0];
            $a = explode(Show_App::config()->url->separator, $controller);
            if (count($a) > 1) {
                foreach ($a as $k => $v) {
                    if ($v === '') {
                        unset($a[$k]);
                    }
                }
                $controller = implode('_', $a);
            }
        }
        $this->controllerName = 'Controller_' . $controller;
    }
    
    /**
     * 初始化Action名称
     *
     * @return void
     */
    protected function initActionName()
    {
        if (!empty($GLOBALS['show']['command_stack'][1])) {
            $this->actionName = $GLOBALS['show']['command_stack'][1];
        } else {
            $this->actionName = Show_App::config()->url->default->action;
        }
    }
    
    /**
     * 检查控制器中是否有对应action的method
     * 
     * @return bool
     */
    protected function actionExist()
    {
        if ($this->actionName == 'init' || $this->actionName == 'setModel' || $this->actionName == 'setView') {
            return false;
        }
        return method_exists($this->controller, $this->actionName);
    }
    
    /**
     * 实例化控制器类
     * 如果无法找到控制器类，则初始化为null
     *
     * @return void
     */
    protected function instanceController()
    {
        if (defined('APP_ROOT')) {
            $filename = str_replace('_', '/', $this->controllerName);
            $path = APP_ROOT . $filename . '.php';
            if (!file_exists($path)) {
                $this->_404();
            }
            include_once $path;
            if (class_exists($this->controllerName, false)) {
                $class = $this->controllerName;
                $this->controller = new $class();
            } else {
                $this->controller = null;
            }
        }
    }
    
    
    /**
     * 去除伪静态url的后缀
     *
     * @param string $cmd 系统命令
     * @return string 去除后缀的url
     */
    protected function decodeUnrealHtml($cmd)
    {
        $pos = strpos($cmd, '.' . UNREAL_HTML);
        if ($pos) {
            return substr($cmd, 0, $pos);
        } else {
            return $pos;
        }
    }
}
?>